//
// Created by lz on 3/7/21.
//

#ifndef MYWEBLIB_BASE_WEAKCALLBACK_H_
#define MYWEBLIB_BASE_WEAKCALLBACK_H_

#include <functional>
#include <memory>

namespace lzweb
{

	// A barely usable WeakCallback
	template<typename CLASS,typename ... ARGS>
	class WeakCallback
	{
	 public:
		WeakCallback(const std::weak_ptr<CLASS>& object,
			const std::function<void(CLASS*, ARGS...)>& function)
			: object_(object), function_(function)
		{

		}
		// Default dtor, copy ctor and assignment are okay

		//模板类&&代表perfect_forward，即会自动识别传进的是左值还是右值
		void operator()(ARGS&&... args) const
		{
			std::shared_ptr<CLASS> ptr(object_.lock());
			if(ptr)
			{
				function_(ptr.get(),std::forward<ARGS>(args) ...);
			}
		}

	 private:

		std::weak_ptr<CLASS> object_;
	 	std::function<void(CLASS*, ARGS...)> function_;
	};

	//用到类成员函数指针，因为类成员函数有一个隐含的该类指针参数
	template<typename CLASS, typename... ARGS>
	WeakCallback<CLASS, ARGS...> makeWeakCallback(const std::shared_ptr<CLASS>& object,
		void (CLASS::*function)(ARGS...))
	{
		return WeakCallback<CLASS, ARGS...>(object, function);
	}


	//const 成员函数版本     const成员函数的原理是隐含的this指针为const，因此算是非const版本的一种重载
	template<typename CLASS, typename... ARGS>
	WeakCallback<CLASS, ARGS...> makeWeakCallback(const std::shared_ptr<CLASS>& object,
		void (CLASS::*function)(ARGS...) const)
	{
		return WeakCallback<CLASS, ARGS...>(object, function);
	}

} // namespace lzweb

#endif //MYWEBLIB_BASE_WEAKCALLBACK_H_
